<template>
    <el-card class="box-card">
        <!-- 卡片顶部添加品牌的按钮 -->
        <el-button type="primary" size="default" icon="Plus" @click="addTrademark" v-has="`btn.Trademark.add`">添加品牌</el-button>
        <!-- 表格组件：用于展示已有的平台数据 -->
        <!-- 
            table
            -----border：设置表格纵向是否有边框
            table-column
            -----label：列标题
            -----width：列宽度
            -----align：列对齐方式
            -----type：列的类型
         -->
        <el-table style="margin:10px 0px ;" border :data="trademarkArr">
            <el-table-column label="序号" width="80px" align="center" type="index"></el-table-column>
            <!-- table-column默认展示数据使用div -->
            <!-- 也可以使用作用域插槽展示 -->
            <el-table-column label="品牌名称">
                <template #="{row, column, $index}">
                    <pre style="color: brown;">{{ row.tmName }}</pre>
                </template>
            </el-table-column>
            <el-table-column label="品牌LOGO">
                <template #="{row, column, $index}">
                    <img :src="row.logoUrl" alt="未有图片" style="width: 100px;height: 100px;">
                </template>
            </el-table-column>
            <el-table-column label="品牌操作">
                <template #="{row, column, $index}">
                    <el-button type="primary" size="small" icon="Edit" @click="updateTrademark(row)" v-has="`btn.Trademark.update`"></el-button>
                    <el-popconfirm :title="`您确定要删除${row.tmName}吗`" width="250px" icon="Delete" @confirm="removeTrademark(row.id)">
                        <template #reference>
                            <el-button type="primary" size="small" icon="Delete" v-has="`btn.Trademark.remove`"></el-button>
                        </template>
                    </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>
        <!-- 分页器组件 -->
        <!-- 
            v-model:current-page:当前显示页码
            v-model:page-size:每页展示数据条数
            page-sizes:下拉菜单数据
            small：是否使用小型分页样式
            background：按钮背景色
            layout：调整子组件布局
            pager-count:设置最大页码按钮数
         -->
        <el-pagination
            v-model:current-page="pageNo"
            v-model:page-size="limit"
            :page-sizes="[3, 5, 7, 9]"
            :small="false"
            :background="true"
            layout="prev, pager, next, jumper,->, sizes,total"
            :total="total"
            :pager-count="9"
            @current-change="changePageNo"
            @size-change="sizeChange"
        />
    </el-card>
    <!-- 对话框业务 -->
    <!-- 
        v-model：用于控制对话框显示或隐藏 true显示 false隐藏
        title：设置对话框左上角标题
     -->
    <el-dialog v-model="dialogFormVisible" :title="trademarkParams.id?'修改品牌':'添加品牌'">
        <el-form style="width:80%" :model="trademarkParams" :rules="rules" ref="formRef">
            <!-- label-width:设置标签宽度，让标签对其 -->
            <el-form-item label="品牌名称" label-width="100px" prop="tmName">
                <el-input placeholder="请您输入品牌名称" v-model="trademarkParams.tmName"></el-input>
            </el-form-item>
            <el-form-item label="品牌LOGO" label-width="100px" prop="logoUrl">
                <!-- 
                    action:上传图片的请求地址,路径需补全/api,否则代理服务器不发送这次请求
                    show-file-list：是否显示已上传文件列表
                    before-upload:上传文件之前的钩子，参数为上传的文件【可以约束文件类型、大小】
                    on-success：文件上传成功的钩子
                 -->
                <el-upload
                    class="avatar-uploader"
                    action="/api/admin/product/fileUpload"
                    :show-file-list="false"
                    :on-success="handleAvatarSuccess"
                    :before-upload="beforeAvatarUpload"
                >
                    <img v-if="trademarkParams.logoUrl" :src="trademarkParams.logoUrl" class="avatar" />
                    <el-icon v-else class="avatar-uploader-icon">
                        <Plus />
                    </el-icon>
                </el-upload>
            </el-form-item>
        </el-form>
        <!-- 具名插槽:footer -->
        <template #footer>
            <el-button type="primary" size="default" @click="cancel">取消</el-button>
            <el-button type="primary" size="default" @click="confirm">确定</el-button>
        </template>
    </el-dialog>
</template>

<script lang="ts" setup name="TradeMark">
    import {ref,onMounted,reactive,nextTick} from 'vue'
    import {reqHasTradeMark,reqAddOrUpdateTradeMark,reqDeleteTrademark} from '@/api/product/trademark'
    import type {Recoeds,TradeMarkResponseData,Trademark} from '@/api/product/trademark/type'
    import type { UploadProps } from 'element-plus'
    import {ElMessage} from 'element-plus'

    // 分页器当前页码
    let pageNo=ref<number>(1)
    // 每页展示数据条数
    let limit=ref<number>(3)
    // 数据总量
    let total=ref<number>(0)
    // 存储已有品牌的数据，是一个数组
    let trademarkArr=ref<Recoeds>([])
    // 控制对话框显示或隐藏
    let dialogFormVisible=ref<boolean>(false)
    // 定义一个收集新增品牌数据
    let trademarkParams=reactive<Trademark>({
        tmName:'',
        logoUrl:''
    })
    // 表单校验规则对象
    const rules={
        tmName:[
            {required:true,trigger:'blur',validator:validatorTmName}
        ],
        logoUrl:[
            {required:true,trigger:'blur',validator:validatorLogoUrl}
        ]
    }
    // 获取el-form组件实例
    let formRef=ref()

    // 获取已有品牌
    async function getHasTradeMark(pager=1){
        // 当前页码
        pageNo.value=pager
        let result:TradeMarkResponseData=await reqHasTradeMark(pageNo.value,limit.value)
        if(result.code==200){
            // 存储已有品牌总个数
            total.value=result.data.total
            // 存储已有品牌的数据
            trademarkArr.value=result.data.records
        }
    }
    
    // 组件挂载完毕:获取第一页、一页三个已有品牌数据
    onMounted(()=>{
        getHasTradeMark()
    })

    // 分页器当前页码发生变化会触发
    // 对于当前页码发生变化这个自定义事件，组件pagination父组件回传了参数（当前页码）
    function changePageNo(){
        // 当前页码发生变化时，再次发送请求获取对应已有品牌的数据
        getHasTradeMark(pageNo.value)
    }

    // 当下拉菜单发生变化的时候会触发方法
    // 对于该自定义事件，父组件也会自动注入下拉菜单选中的数值
    function sizeChange(){
        // 当前每页的数据量发生变化，让其当前页码回到1，可以给其一个默认参数pager
        getHasTradeMark()
    }

    // 添加品牌按钮的回调
    function addTrademark(){
        // 对话框显示
        dialogFormVisible.value=true
        // 清空收集数据
        trademarkParams.tmName=''
        trademarkParams.logoUrl=''
        trademarkParams.id=0
        // 清除表单验证信息 注意：刚开始form组件还没创建
        // 第一种方法 ts?
        // formRef.value?.clearValidate('tmName')
        // formRef.value?.clearValidate('logoUrl')
        // 第二种方法 nextTick
        nextTick(()=>{
            formRef.value.clearValidate('tmName')
            formRef.value.clearValidate('logoUrl')
        })
    }

    // 修改已有按钮品牌的回调
    // row即为当前已有的品牌
    function updateTrademark(row:Trademark){
        // 清空表单校验提示信息
        nextTick(()=>{
            formRef.value.clearValidate('tmName')
            formRef.value.clearValidate('logoUrl')
        })
        // 对话框显示
        dialogFormVisible.value=true
        trademarkParams.id=row.id
        // 展示已有品牌的数据
        trademarkParams.tmName=row.tmName
        trademarkParams.logoUrl=row.logoUrl
    }

    // 对话框底部取消按钮
    function cancel(){
        // 对话框隐藏
        dialogFormVisible.value=false
    }

    // 对话框底部确定按钮
    async function confirm(){
        // 请求前对所有表单进行校验
        // 调用这个方法进行全部表单校验，如果校验全部通过，再执行之后的语句
        await formRef.value.validate()
        // 给服务器发请求
        let result:any=await reqAddOrUpdateTradeMark(trademarkParams)
        // 添加|修改品牌成功
        if(result.code==200){
            // 对话框关闭
            dialogFormVisible.value=false
            // 弹出提示信息
            ElMessage({
                type:'success',
                message:trademarkParams.id?'修改品牌成功':'添加品牌成功'
            })
            // 发请求获取已有全部品牌的数据
            getHasTradeMark(trademarkParams.id?pageNo.value:1)
        }else{
            // 添加品牌失败
            // 对话框关闭
            dialogFormVisible.value=false
            // 弹出提示信息
            ElMessage({
                type:'error',
                message:trademarkParams.id?'修改品牌失败':'添加品牌失败'
            })
        }
        
    }
    
    // 图片上传前的钩子
    const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
        // 钩子在图片上传之前触发,可以约束文件类型和大小
        // 要求：上传文件格式png|jpg|gif|jpeg <=4M
        if(rawFile.type=='image/png'||rawFile.type=='image/jpg'||rawFile.type=='image/gif'||rawFile.type=='image/jpeg'){
            if(rawFile.size/1024/1024<4){
                return true
            }else{
                ElMessage({
                    type:'error',
                    message:'上传文件大小应小于4M'
                })
                return false
            }
        }else{
            ElMessage({
                type:'error',
                message:'上传文件格式务必是PNG|JPG|JPEG|GIF'
            })
            return false
        }
    }

    // 文件上传成功的钩子
    // response：即为当前这次上传图片post请求服务器返回的数据
    // uploadFile：图片信息
    const handleAvatarSuccess: UploadProps['onSuccess'] = (response,uploadFile) => {
        // 收集上传图片的地址
        trademarkParams.logoUrl=response.data
        // 图片上传成功，清除掉图片校验结果
        formRef.value.clearValidate('logoUrl')
    }

    // 品牌名称自定义校验规则方法
    // value：表单文本内容 callBack：放行函数
    function validatorTmName(rule:any,value:any,callBack:any){
        // 文字内容大于两位
        if(value.trim().length>=2){
            callBack()
        }else{
            // 校验未通过，返回错误信息
            callBack(new Error('品牌名称位数需大于等于两位'))
        }
    }

    // 品牌LOGO图片自定义校验规则方法
    // value:图片地址
    function validatorLogoUrl(rule:any,value:any,callBack:any){
        if(value){
            callBack()
        }else{
            callBack(new Error('LOGO图片务必上传'))
        }
    }

    // 气泡确认框确定按钮的回调
    async function removeTrademark(id:number){
        // 发送请求删除已有品牌
        let result=await reqDeleteTrademark(id)
        if(result.code==200){
            // 删除成功
            ElMessage({
                type:'success',
                message:'删除品牌成功'
            }) 
            // 再次获取已有的品牌数据
            getHasTradeMark(trademarkArr.value.length>1?pageNo.value:pageNo.value-1)
        }else{
            ElMessage({
                type:'error',
                message:'删除品牌失败'
            }) 
        }
    }

</script>

<style scoped>
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>